/**
 * 
 */
package lt.vin.currency.client.ui;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lt.vin.currency.client.service.CurrencyService;
import lt.vin.currency.client.service.CurrencyServiceAsync;
import lt.vin.currency.shared.Source;
import lt.vin.currency.shared.TestResult;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.weborient.codemirror.client.CodeMirrorEditorWidget;

/**
 * @author Vincentas
 *
 */
public class AdminUi extends Composite {

	private final CurrencyServiceAsync currencyService = GWT.create(CurrencyService.class);
	
	private static CurrencyUIUiBinder uiBinder = GWT.create(CurrencyUIUiBinder.class);

	interface CurrencyUIUiBinder extends UiBinder<Widget, AdminUi> {
	}

	@UiField
	ListBox sources;
	
	@UiField
	Button newButton;
	
	@UiField
	TextBox bankCode;
	
	@UiField
	TextBox url;
	
	@UiField
	CodeMirrorEditorWidget transformation;
		
	@UiField
	CodeMirrorEditorWidget rawResult;
	
	@UiField
	CodeMirrorEditorWidget testResult;
	
	@UiField
	Button testButton;
	
	@UiField
	Button saveButton;
	
	private Map<String, Source> allSources = new HashMap<String, Source>();
	
	public AdminUi() {
		initWidget(uiBinder.createAndBindUi(this));
		
		currencyService.getSources(new AsyncCallback<List<Source>>() {
			
			@Override
			public void onSuccess(List<Source> result) {
				for (Source source : result) {
					sources.addItem(source.getBankCode(), source.getBankCode());
					allSources.put(source.getBankCode(), source);
				}	
				
				Source source = selectedSource();
				lastSource = source;
				bankCode.setText(source.getBankCode());
				url.setText(source.getUrl());
				transformation.setText(source.getTransformation());
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Fail : " + caught.getMessage());
			}
		});
	}
	
	@UiHandler("url")
	void urlChanged(ChangeEvent e) {
		selectedSource().setUrl(url.getText());
	}
	
	private Source lastSource;
	
	@UiHandler("sources")
	void sourcesItemSelected(ChangeEvent e) {		
		lastSource.setTransformation(transformation.getText());
		
		Source source = selectedSource();
		lastSource = source;
		
		bankCode.setText(source.getBankCode());
		url.setText(source.getUrl());
		transformation.setText(source.getTransformation());
	}
	
	@UiHandler("newButton")
	void onNewClick(ClickEvent e) {
		String value = bankCode.getText();
		if (value.isEmpty()) {
			Window.alert("Enter bank code");
		} else if (allSources.containsKey(value)) {
			Window.alert("Source already exists");
		} else {
			Source source = new Source(value, url.getText(), transformation.getText());
			allSources.put(value, source);
			sources.addItem(value, value);
		}
	}
	@UiHandler("testButton")
	void onTestClick(ClickEvent e) {
		currencyService.testSource(selectedSource(), new AsyncCallback<TestResult>() {
			
			@Override
			public void onSuccess(TestResult result) {
				testResult.setText(result.getData());
				rawResult.setText(result.getRawData());
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Fail : " + caught.getMessage());				
			}
		});
	}
	@UiHandler("saveButton")
	void onSaveClick(ClickEvent e) {
		currencyService.saveSource(selectedSource(), new AsyncCallback<Void>() {
			
			@Override
			public void onSuccess(Void result) {
				Window.alert("Saved");				
			}
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Fail : " + caught.getMessage());				
			}
		});
	}
	
	private Source selectedSource() {
		return allSources.get(sources.getValue(sources.getSelectedIndex()));
	}

}
